<script type="text/javascript">
        var gk_isXlsx = false;
        var gk_xlsxFileLookup = {};
        var gk_fileData = {};
        function filledCell(cell) {
          return cell !== '' && cell != null;
        }
        function loadFileData(filename) {
        if (gk_isXlsx && gk_xlsxFileLookup[filename]) {
            try {
                var workbook = XLSX.read(gk_fileData[filename], { type: 'base64' });
                var firstSheetName = workbook.SheetNames[0];
                var worksheet = workbook.Sheets[firstSheetName];

                // Convert sheet to JSON to filter blank rows
                var jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, blankrows: false, defval: '' });
                // Filter out blank rows (rows where all cells are empty, null, or undefined)
                var filteredData = jsonData.filter(row => row.some(filledCell));

                // Heuristic to find the header row by ignoring rows with fewer filled cells than the next row
                var headerRowIndex = filteredData.findIndex((row, index) =>
                  row.filter(filledCell).length >= filteredData[index + 1]?.filter(filledCell).length
                );
                // Fallback
                if (headerRowIndex === -1 || headerRowIndex > 25) {
                  headerRowIndex = 0;
                }

                // Convert filtered JSON back to CSV
                var csv = XLSX.utils.aoa_to_sheet(filteredData.slice(headerRowIndex)); // Create a new sheet from filtered array of arrays
                csv = XLSX.utils.sheet_to_csv(csv, { header: 1 });
                return csv;
            } catch (e) {
                console.error(e);
                return "";
            }
        }
        return gk_fileData[filename] || "";
        }
        </script>```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>学生成绩管理系统</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
    .container { max-width: 800px; margin: 0 auto; }
    .form-section, .table-section { background: #fff; padding: 20px; margin-bottom: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
    .form-group { display: flex; gap: 20px; margin-bottom: 15px; }
    .form-group div { flex: 1; }
    input { width: 100%; padding: 8px; border: 1px solid #ccc; border-radius: 4px; }
    .error { color: red; font-size: 12px; }
    button { padding: 8px 16px; background: #007bff; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
    button:hover { background: #0056b3; }
    table { width: 100%; border-collapse: collapse; }
    th, td { padding: 12px; text-align: left; border-top: 1px solid #ddd; }
    th { background: #f8f9fa; position: sticky; top: 0; }
    tr:hover { background: #f1f1f1; }
    .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); justify-content: center; align-items: center; }
    .modal-content { background: #fff; padding: 20px; border-radius: 8px; max-width: 400px; width: 100%; }
    .table-container { max-height: 400px; overflow-y: auto; }
    select { padding: 8px; border-radius: 4px; }
  </style>
</head>
<body>
  <div class="container">
    <!-- 成绩录入表单 -->
    <div class="form-section">
      <h2>添加学生成绩</h2>
      <form id="studentForm" onsubmit="addStudent(event)">
        <div class="form-group">
          <div>
            <label>姓名</label>
            <input type="text" id="name" required>
            <span id="nameError" class="error"></span>
          </div>
          <div>
            <label>数学成绩</label>
            <input type="number" id="math" min="0" max="100" required>
            <span id="mathError" class="error"></span>
          </div>
          <div>
            <label>英语成绩</label>
            <input type="number" id="english" min="0" max="100" required>
            <span id="englishError" class="error"></span>
          </div>
        </div>
        <button type="submit">添加</button>
      </form>
    </div>

    <!-- 成绩列表 -->
    <div class="table-section">
      <h2>学生成绩列表
        <select id="sortKey" onchange="sortStudents()">
          <option value="">默认排序</option>
          <option value="math">按数学成绩</option>
          <option value="english">按英语成绩</option>
          <option value="average">按平均分</option>
        </select>
      </h2>
      <div class="table-container" id="tableContainer" onscroll="handleScroll()">
        <table>
          <thead>
            <tr>
              <th>姓名</th>
              <th>数学</th>
              <th>英语</th>
              <th>平均分</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody id="studentTable"></tbody>
        </table>
      </div>
    </div>

    <!-- 学生详情弹窗 -->
    <div id="modal" class="modal">
      <div class="modal-content">
        <h2 id="modalTitle"></h2>
        <p id="modalMath"></p>
        <p id="modalEnglish"></p>
        <p id="modalAverage"></p>
        <button onclick="closeModal()">关闭</button>
      </div>
    </div>
  </div>

  <script>
    let students = [
      { id: 1, name: "张三", math: 90, english: 85 },
      { id: 2, name: "李四", math: 78, english: 92 }
    ];
    let sortKey = '';
    const itemHeight = 48; // 每行高度（像素）
    let startIndex = 0;
    let visibleCount = 10;

    // 表单验证
    function validateForm(name, math, english) {
      let valid = true;
      document.getElementById('nameError').textContent = '';
      document.getElementById('mathError').textContent = '';
      document.getElementById('englishError').textContent = '';

      if (!name.trim()) {
        document.getElementById('nameError').textContent = '姓名不能为空';
        valid = false;
      }
      if (math < 0 || math > 100 || isNaN(math)) {
        document.getElementById('mathError').textContent = '数学成绩需在0-100之间';
        valid = false;
      }
      if (english < 0 || english > 100 || isNaN(english)) {
        document.getElementById('englishError').textContent = '英语成绩需在0-100之间';
        valid = false;
      }
      return valid;
    }

    // 添加学生
    function addStudent(event) {
      event.preventDefault();
      const name = document.getElementById('name').value;
      const math = parseInt(document.getElementById('math').value);
      const english = parseInt(document.getElementById('english').value);

      if (!validateForm(name, math, english)) return;

      students.push({
        id: students.length + 1,
        name: name.trim(),
        math,
        english
      });
      document.getElementById('studentForm').reset();
      renderTable();
    }

    // 删除学生
    function deleteStudent(id) {
      students = students.filter(student => student.id !== id);
      renderTable();
    }

    // 计算平均分
    function getAverage(student) {
      return (student.math + student.english) / 2;
    }

    // 显示学生详情
    function showDetail(student) {
      document.getElementById('modalTitle').textContent = `${student.name} 的成绩详情`;
      document.getElementById('modalMath').textContent = `数学成绩：${student.math}`;
      document.getElementById('modalEnglish').textContent = `英语成绩：${student.english}`;
      document.getElementById('modalAverage').textContent = `平均分：${getAverage(student).toFixed(1)}`;
      document.getElementById('modal').style.display = 'flex';
    }

    // 关闭弹窗
    function closeModal() {
      document.getElementById('modal').style.display = 'none';
    }

    // 排序学生列表
    function sortStudents() {
      sortKey = document.getElementById('sortKey').value;
      if (sortKey) {
        students.sort((a, b) => {
          if (sortKey === 'average') {
            return getAverage(b) - getAverage(a);
          }
          return b[sortKey] - a[sortKey];
        });
      }
      startIndex = 0; // 重置滚动位置
      renderTable();
    }

    // 虚拟滚动实现
    function renderTable() {
      const tbody = document.getElementById('studentTable');
      tbody.innerHTML = '';
      const visibleStudents = students.slice(startIndex, startIndex + visibleCount);
      visibleStudents.forEach(student => {
        const tr = document.createElement('tr');
        tr.innerHTML = `
          <td><button onclick='showDetail(${JSON.stringify(student)})' style="color: #007bff; background: none; border: none; cursor: pointer;">${student.name}</button></td>
          <td>${student.math}</td>
          <td>${student.english}</td>
          <td>${getAverage(student).toFixed(1)}</td>
          <td><button onclick="deleteStudent(${student.id})" style="color: #dc3545;">删除</button></td>
        `;
        tbody.appendChild(tr);
      });
    }

    // 处理滚动事件
    function handleScroll() {
      const scrollTop = document.getElementById('tableContainer').scrollTop;
      startIndex = Math.floor(scrollTop / itemHeight);
      renderTable();
    }

    // 更新可视行数
    function updateVisibleCount() {
      const container = document.getElementById('tableContainer');
      visibleCount = Math.ceil(container.clientHeight / itemHeight) + 2; // 缓冲2行
      renderTable();
    }

    // 初始化
    window.onload = () => {
      updateVisibleCount();
      window.addEventListener('resize', updateVisibleCount);
    };
  </script>
</body>
</html>
```